from datetime import datetime
import json

from utils.printSelf import printSelf,log_info,redPrint
from models.models import db,People,Maxims,Article,FuturesDetailInfo,FuturesDetailInfoHistory,FuturesTradeDayStatus,Trade, \
    default_serializer

def calculateEMA(data, period):
    ema_values = []
    multiplier = 2 / (period + 1)
    ema = None

    for value in data:
        if ema is None:
            ema = value
        else:
            ema = (value - ema) * multiplier + ema
        ema_values.append(ema)

    return ema_values

def calculateMACD(last14toNext15Details, short_period=12, long_period=26, m_period=9):
    data=last14toNext15Details["detailsMinute"]
    #print(len(data))
    price_data = [item['lastDetail']["price"] for item in data]

    if len(price_data) < long_period:
        return []

    short_ema = calculateEMA(price_data, short_period)
    long_ema = calculateEMA(price_data, long_period)

    dif = [short - long for short, long in zip(short_ema, long_ema)]
    dea = calculateEMA(dif, m_period)

    macd = [(d - d_ea) * 2 for d, d_ea in zip(dif, dea)]

    for i in range(len(macd)):
        data[i]['macd'] = macd[i]#贴标
        data[i]['dif'] = dif[i]
        data[i]['dea'] = dea[i]
    #log_info(redPrint(f"macd的长度:{len(macd)}"))
    #return data

#收集每分钟的成交量和每分最后一个交易
def collectMinuteDetails(last14toNext15Details):
    timeObj21Tamp=last14toNext15Details["timeObj21Tamp"]

    #log_info("collectMinuteDetails开始")
    data=last14toNext15Details["details"]
    #log_info("单级数据的长度:"+str(len(data)))
    #判断last14toNext15Details["detailsMinute"]是否存在
    if "detailsMinute" in last14toNext15Details:
        minute_details = last14toNext15Details["detailsMinute"]
    else:
        last14toNext15Details["detailsMinute"]=[]
        minute_details = last14toNext15Details["detailsMinute"]
    #log_info("单级数据的长度:"+str(len(data)))
    for i in range(len(data)):

        item=data[i]
        #log_info(item)
        minute_key = (int(item["time"]) // 60) * 60
        dateObj=datetime.fromtimestamp(minute_key)
        if dateObj.hour==20 and dateObj.minute==59:
            continue
        #log_info("minute_key is :"+str(minute_key))
        demoJson={}
        for j in range(len(minute_details)): #在已有的分钟级数据中找到归属
            if minute_key==minute_details[j]["minute"]:
                demoJson=minute_details[j]
                break
        #log_info("存在信号:"+json.dumps(demoJson))
        if demoJson=={}: #在以后的分钟级数据中找不到归属,即不存在
            #log_info("分钟级key 不存在")
            demoJson={'minute': minute_key,'lastDetail': item,'volumeB': 0,'volumeS': 0,'averagePrice': 0,
                      "total_volume":0,"total_amount":0,"openPrice":item["price"],"closePrice":item["price"],"highPrice": item["price"],"lowPrice": item["price"],"centerPrice":item["price"]}
            if item["bsFlag"] == 'B':
                demoJson['volumeB'] += int(item["volume"])
            elif item["bsFlag"] == 'S':
                demoJson['volumeS'] += int(item["volume"])
            #log_info("收集完一单一部分:"+json.dumps(demoJson))
            if minute_key>=timeObj21Tamp:  #成交量和金额应该只统计21点以后的
                #log_info("当前key大于21点key")
                if datetime.fromtimestamp(minute_key).hour==21 and datetime.fromtimestamp(minute_key).minute==0:
                    demoJson['total_volume']=int(item["volume"])
                    demoJson['total_amount']=int(item["volume"]) * int(item["price"])
                else:
                    #取这一分钟的前一个的总量加上这一分钟的总量
                    prev_minute_detail=0
                    for n in range(len(minute_details)):
                        if minute_details[n]["minute"]>minute_key:
                            prev_minute_detail=minute_details[n-1]
                            # print("找到了")
                            break
                    if prev_minute_detail==0 :
                        if len(minute_details)==0:return
                        prev_minute_detail=minute_details[-1]
                        # print("prev_minute_detail"+str(prev_minute_detail))
                        # print("现在的时间戳是:"+str(minute_key))
                    demoJson['total_volume']=prev_minute_detail['total_volume']+int(item["volume"])
                    demoJson['total_amount']=prev_minute_detail['total_amount']+int(item["volume"]) * int(item["price"])
                demoJson["averagePrice"]=demoJson['total_amount']/demoJson['total_volume']
            #log_info("收集完一单:"+json.dumps(demoJson))
            minute_details.append(demoJson)

        else:
            demoJson["lastDetail"]=item
            if item["bsFlag"] == 'B':
                demoJson['volumeB'] += int(item["volume"])
            elif item["bsFlag"] == 'S':
                demoJson['volumeS'] += int(item["volume"])
            #if minute_key>=timeObj21Tamp: #成交量和金额应该只统计21点以后的
            demoJson["total_volume"]+=int(item["volume"])
            demoJson['total_amount']=demoJson['total_amount']+int(item["volume"]) * int(item["price"])
            demoJson["averagePrice"]=demoJson['total_amount']/demoJson['total_volume']
            #收集价格最高和最低
            demoJson["closePrice"]=item["price"]
            if item["price"]>demoJson["highPrice"]:
                demoJson["highPrice"]=item["price"]
            if item["price"]<demoJson["lowPrice"]:
                demoJson["lowPrice"]=item["price"]
            demoJson["centerPrice"]=(demoJson["highPrice"]+demoJson["lowPrice"])/2

    #print(minute_details)
    #last14toNext15Details["details"]=[]
    log_info("刚刚计算出来的分钟级数据长度:"+str(len(last14toNext15Details["detailsMinute"])))


    # for i in range(len(last14toNext15Details["detailsMinute"])):
    #     item=last14toNext15Details["detailsMinute"][i]
    #     if last14toNext15Details["detailsMinute"][i]["minute"]<timeObj21Tamp: continue
    #     if total_amount==0:
    #         last14toNext15Details["detailsMinute"][i]["total_amount"]=item["volumeB"]
    #         last14toNext15Details["detailsMinute"][i]["total_amount"]=last14toNext15Details["detailsMinute"][i]["total_amount"]+item["volumeS"]
    #
    #
    #
    #
    #     total_amount=total_amount+int(item["total_amount"])
    #     total_volume=total_volume+int(item["total_volume"])
    #     if total_volume>0:
    #         item["averagePrice"]=total_amount/total_volume
        # # 更新总交易量和总金额
        # total_volume += int(item["volume"])
        # total_amount += int(item["volume"]) * item["price"]
        #
        # # 如果 total_volume 不为零，计算平均价格
        # if total_volume > 0:
        #     minute_details[minute_key]['averagePrice'] = total_amount / total_volume

    # # 将字典转换为列表
    # one_minute_last_detail = []
    # for minute_key, detail in minute_details.items():
    #     one_minute_last_detail.append({
    #         'minute': minute_key,
    #         'lastDetail': detail['lastDetail'],
    #         'volumeB': detail['volumeB'],
    #         'volumeS': detail['volumeS'],
    #         'averagePrice': detail['averagePrice'],
    #     })
    # #print("经过处理后,一分钟数据的长度是:"+str(len(one_minute_last_detail)))
    # last14toNext15Details["details"]=[]
    # return one_minute_last_detail

#收集每分钟的成交量
def collectMinuteVolume(futuresDetailInfos):
    minute_details =[]
    #把futuresDetailInfos 变成字典
    futuresDetailInfosArray=[]
    for i in range(len(futuresDetailInfos)):
        item=futuresDetailInfos[i].to_dict()
        futuresDetailInfosArray.append(item)
    for i in range(len(futuresDetailInfosArray)):
        item=futuresDetailInfosArray[i]
        #log_info(item)
        minute_key = (int(item["time"]) // 60) * 60
        dateObj=datetime.fromtimestamp(minute_key)
        if dateObj.hour==20 and dateObj.minute==59:
            continue
        #log_info("minute_key is :"+str(minute_key))
        minuteJson={}
        for j in range(len(minute_details)): #在已有的分钟级数据中找到归属
            if minute_key==minute_details[j]["minute"]:
                minuteJson=minute_details[j]
                break
        #log_info("存在信号:"+json.dumps(demoJson))
        if minuteJson=={}: #在以后的分钟级数据中找不到归属,即不存在
            #log_info("分钟级key 不存在")
            minuteJson={'minute': minute_key,'volumeB': 0,'volumeS': 0}
            if item["bsFlag"] == 'B':
                minuteJson['volumeB'] += int(item["volume"])
            elif item["bsFlag"] == 'S':
                minuteJson['volumeS'] += int(item["volume"])
            minute_details.append(minuteJson)
        else:
            if item["bsFlag"] == 'B':
                minuteJson['volumeB'] += int(item["volume"])
            elif item["bsFlag"] == 'S':
                minuteJson['volumeS'] += int(item["volume"])
    #删除前5个最大的成交量
    for i in range(5):
        minute_details=removeMaxVolume(minute_details)

    #重新计算最大成交量
    maxVolume=0
    for n in range(len(minute_details)):
        if minute_details[n]["volumeB"]>maxVolume:     maxVolume=minute_details[n]["volumeB"]
        if minute_details[n]["volumeS"]>maxVolume:     maxVolume=minute_details[n]["volumeS"]

    dayJson={}
    dayJson["minute_details"]=minute_details
    dayJson["maxVolume"]=maxVolume

    return dayJson

#找到最大成交量,删除这一分钟的数据
def removeMaxVolume(minute_details):
    #重新计算最大成交量
    maxVolume=0
    for n in range(len(minute_details)):
        if minute_details[n]["volumeB"]>maxVolume:     maxVolume=minute_details[n]["volumeB"]
        if minute_details[n]["volumeS"]>maxVolume:     maxVolume=minute_details[n]["volumeS"]
    #找到最大成交量,删除这一分钟的数据
    for n in range(len(minute_details)):
        #log_info("n:"+str(n))
        #log_info("len(minute_details):"+str(len(minute_details)))
        if minute_details[n]["volumeB"]==maxVolume or minute_details[n]["volumeS"]==maxVolume:
            #从minute_details中删除这一行数据
            minute_details.pop(n)
            break

    return minute_details


#收集每3分钟的成交量和每3分最后一个交易
def collect3MinuteDetails(last14toNext15Details):
    timeObj21Tamp=last14toNext15Details["timeObj21Tamp"]

    #log_info("collectMinuteDetails开始")
    data=last14toNext15Details["details"]
    #log_info("单级数据的长度:"+str(len(data)))
    #判断last14toNext15Details["detailsMinute"]是否存在
    if "details3Minute" in last14toNext15Details:
        minute3_details = last14toNext15Details["details3Minute"]
    else:
        last14toNext15Details["details3Minute"]=[]
        minute3_details = last14toNext15Details["details3Minute"]
    #log_info("单级数据的长度:"+str(len(data)))
    for i in range(len(data)):

        item=data[i]
        #log_info(item)
        minute3_key = (int(item["time"]) // 180) * 180
        dateObj=datetime.fromtimestamp(minute3_key)
        if dateObj.hour==20 and dateObj.minute==59:
            continue
        #log_info("minute_key is :"+str(minute_key))
        demoJson={}
        for j in range(len(minute3_details)): #在已有的分钟级数据中找到归属
            if minute3_key==minute3_details[j]["minute3"]:
                demoJson=minute3_details[j]
                break
        #log_info("存在信号:"+json.dumps(demoJson))
        if demoJson=={}: #在以后的分钟级数据中找不到归属,即不存在
            #log_info("分钟级key 不存在")
            demoJson={'minute3': minute3_key,'lastDetail': item,"openPrice":item["price"],"closePrice":item["price"],
                      "highPrice": item["price"],"lowPrice": item["price"],"centerPrice":item["price"]}
            minute3_details.append(demoJson)
        else:
            #收集价格最高和最低
            demoJson["closePrice"]=item["price"]
            if item["price"]>demoJson["highPrice"]:
                demoJson["highPrice"]=item["price"]
            if item["price"]<demoJson["lowPrice"]:
                demoJson["lowPrice"]=item["price"]
            demoJson["centerPrice"]=(demoJson["highPrice"]+demoJson["lowPrice"])/2

    #print(minute_details)
    last14toNext15Details["details"]=[]
    log_info("刚刚计算出来的3分钟级数据长度:"+str(len(last14toNext15Details["details3Minute"])))


#计算sar
def calculate_sar(prices, af_start=0.02, af_increment=0.02, af_max=0.2):
    if len(prices) < 2:
        return [], []

    sar_values = []
    trend_directions = []  # 用于记录趋势方向
    uptrend = True  # 初始假设为上升趋势
    af = af_start #初始因子
    ep = prices[0]  # 初始极端值
    sar = ep #起始值
    sar_values.append(sar)
    trend_directions.append("up" if uptrend else "decline")

    for i in range(1, len(prices)):
        prev_price = prices[i - 1]#前一个值
        current_price = prices[i]#当前值

        # 计算新的 SAR
        if uptrend:
            sar = sar + af * (ep - sar)#5881+0.02*(5881-5881)=5881
            if current_price < sar: #如果当前值小于sar
                # 趋势反转
                uptrend = False
                sar = ep
                ep = current_price
                af = af_start
            else:#如果当前值大于sar
                # 更新极端价格
                if current_price > ep:
                    ep = current_price
                # 增加加速因子
                af = min(af + af_increment, af_max)
        else:
            sar = sar + af * (ep - sar)
            if current_price > sar:
                # 趋势反转
                uptrend = True
                sar = ep
                ep = current_price
                af = af_start
            else:
                # 更新极端价格
                if current_price < ep:
                    ep = current_price
                # 增加加速因子
                af = min(af + af_increment, af_max)

        sar_values.append(sar)
        trend_directions.append("up" if uptrend else "decline")

    return sar_values, trend_directions

